﻿/*
Author : Onur "Xtro" ER
Create date : 10.05.2009
Last update : 05.12.2011
*/

using System;
using System.Windows.Forms;
using System.IO;
using FormsMessageBox = System.Windows.Forms.MessageBox;

namespace Xtro.Gerecler
{
    public class EGerecler : Exception
    {
        protected EGerecler(String Message, Exception InnerException = null) : base(Message, InnerException) { }

        protected void Init(string RelevantName, Type RelevantType, string Reason, string ThrowerName)
        {
            Source = RelevantName;
            if (RelevantType != null) Source += " (" + RelevantType + ")";

            this.Reason = Reason;
            this.ThrowerName = ThrowerName;
        }

        public string Reason { get; private set; }
        public string ThrowerName { get; private set; }

        public EGerecler(string RelevantName, Type RelevantType, string Reason, string ThrowerName, Exception InnerException = null) : base(string.Format(ResourcesError.General, RelevantName + " (" + RelevantType + ")"), InnerException) { Init(RelevantName, RelevantType, Reason, ThrowerName); }
    }

    public sealed class EInvalidCall : EGerecler
    {
        public EInvalidCall(string RelevantName, Type RelevantType, string Reason, string ThrowerName, Exception InnerException = null) : base(ResourcesError.InvalidCall, InnerException) { Init(RelevantName, RelevantType, Reason, ThrowerName); }
    }

    public sealed class EInvalidParameter : EGerecler
    {
        public EInvalidParameter(string RelevantName, Type RelevantType, string Reason, string ThrowerName, Exception InnerException = null) : base(string.Format(ResourcesError.InvalidParameter, RelevantName + " (" + RelevantType + ")"), InnerException) { Init(RelevantName, RelevantType, Reason, ThrowerName); }
    }

    public sealed class ENotAvailable : EGerecler
    {
        public ENotAvailable(string RelevantName, string ThrowerName, Exception InnerException = null) : base(string.Format(ResourcesError.NotAvailable, RelevantName), InnerException) { Init(RelevantName, null, "", ThrowerName); }
    }

    // ReSharper disable InconsistentNaming
    public static class ErrorBox
    // ReSharper restore InconsistentNaming
    {
        public static string LogFileName = "GereclerError.log";
        public static bool LogErrors = true;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Exception"></param>
        /// <param name="AbortButton"></param>
        /// <returns>True, if abort button is clicked. Otherwise False.</returns>
        public static bool Show(Exception Exception, bool AbortButton)
        {
            // Don't validate parameters since we don't want to throw a new exception in an error.

            var Result = false;

            try
            {
                var Text = Exception.Message + "\r\n\r\n";

                if (Exception is EGerecler)
                {
                    var E = (EGerecler)Exception;

                    if (Exception is EInvalidCall && !string.IsNullOrEmpty(E.Source)) Text += string.Format("{0,-15}", ResourcesCommon.Relevant) + "\t: " + E.Source + "\r\n";
                    if (!string.IsNullOrEmpty(E.Reason)) Text += string.Format("{0,-15}", ResourcesCommon.Reason) + "\t: " + E.Reason + "\r\n\r\n";
                    if (!string.IsNullOrEmpty(E.ThrowerName)) Text += string.Format("{0,-15}", ResourcesCommon.Thrower) + "\t: " + E.ThrowerName + " (" + E.TargetSite.ReflectedType + ")\r\n";
                }

                Text += string.Format("{0,-15}", ResourcesCommon.Method) + "\t: " + Exception.TargetSite.DeclaringType + "." + Exception.TargetSite.Name + "\r\n" +
                        string.Format("{0,-15}", ResourcesCommon.Date) + "\t: " + DateTime.Now + "\r\n" +
                        string.Format("{0,-15}", ResourcesCommon.Exception) + "\t: " + Exception.GetType() + "\r\n\r\n";

                Text += "- " + ResourcesCommon.CallStack + " -\r\n\r\n" +
                        Exception.StackTrace + "\r\n" +
                        "--------------------------------------------" + "\r\n\r\n";

                var Flags = AbortButton ? MessageBox.NFlags.ContinueAbort : MessageBox.NFlags.Ok;

                MessageBox.Parameters.Options |= MessageBox.NOptions.VistaStyle;

                Result = MessageBox.Show(Text, Application.ProductName, Flags | MessageBox.NFlags.IconError) == MessageBox.NDialogResult.Abort;

                if (LogErrors)
                {
                    var FileStream = File.AppendText(LogFileName);
                    FileStream.Write(Text);
                    FileStream.Close();
                }
            }
            catch (Exception E) { FormsMessageBox.Show(ResourcesCommon.ExceptionInShowError + "\n\n\n" + E); }

            return Result;
        }
    }
}